﻿using System.Collections.Generic;

namespace Raven
{
    public class TargetSystem
    {
        private RavenBot _owner;

        //the current target (this will be null if there is no target assigned)
        private RavenBot _currentTarget;

        public TargetSystem(RavenBot bot)
        {
            _owner = bot;
            _currentTarget = null;
        }

        public void Update()
        {
            Fix ClosestDistSoFar = Fix.MaxValue;
            _currentTarget = null;

            //grab a list of all the opponents the owner can sense
            LinkedList<RavenBot> SensedBots = _owner.GetSensoryMem().GetListOfRecentlySensedOpponents();

            foreach (var curBot in SensedBots)
            {
                //make sure the bot is alive and that it is not the owner
                if (curBot.isAlive() && curBot != _owner)
                {
                    Fix dist = (curBot.Pos() - _owner.Pos()).magnitude;

                    if (dist < ClosestDistSoFar)
                    {
                        ClosestDistSoFar = dist;
                        _currentTarget = curBot;
                    }
                }
            }
        }

        //returns true if there is a currently assigned target
        public bool isTargetPresent()
        {
            return _currentTarget != null;
        }

        //returns true if the target is within the field of view of the owner
        public bool isTargetWithinFOV()
        {
            return _owner.GetSensoryMem().isOpponentWithinFOV(_currentTarget);
        }

        //returns true if there is unobstructed line of sight between the target
        //and the owner
        public bool isTargetShootable()
        {
            return _owner.GetSensoryMem().isOpponentShootable(_currentTarget);
        }

        //returns the position the target was last seen. Throws an exception if
        //there is no target currently assigned
        public Vector2 GetLastRecordedPosition()
        {
            return _owner.GetSensoryMem().GetLastRecordedPositionOfOpponent(_currentTarget);
        }

        //returns the amount of time the target has been in the field of view
        public Fix GetTimeTargetHasBeenVisible()
        {
            return _owner.GetSensoryMem().GetTimeOpponentHasBeenVisible(_currentTarget);
        }

        //returns the amount of time the target has been out of view
        public Fix GetTimeTargetHasBeenOutOfView()
        {
            return _owner.GetSensoryMem().GetTimeOpponentHasBeenOutOfView(_currentTarget);
        }

        //returns a pointer to the target. null if no target current.
        public RavenBot GetTarget()
        {
            return _currentTarget;
        }

        //sets the target pointer to null
        public void ClearTarget()
        {
            _currentTarget = null;
        }
    }
}